﻿using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NewRetail.Application.Components.PrintTask;
using NewRetail.Application.Components.PrintTask.Model;
using NewRetail.Application.Components.Warehouse;
using NewRetail.Application.Components.Warehouse.Entity;
using NewRetail.Application.Core;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;

namespace NewRetail.Api.Controllers
{
    //add by cl 2022.01.26
    [NewRetailRoute("other-bill")]
    public class OtherBillController : BaseController<OtherBill, OtherBillPagingDto>
    {
        private readonly IWarehouseGoodsService warehouseGoodsService;
        private readonly IOtherBillService otherBillService;
        private readonly IPrintTaskService printTaskService;

        public OtherBillController(
            IWarehouseGoodsService warehouseGoodsService,
            IOtherBillService otherBillService, IPrintTaskService printTaskService)
        {
            this.warehouseGoodsService = warehouseGoodsService;
            this.otherBillService = otherBillService;
            this.printTaskService = printTaskService;
        }

        protected override async Task<IQueryable<OtherBill>> FilterQueryPaging(DbContext db, IQueryable<OtherBill> query, OtherBillPagingDto dto)
        {
            if (!string.IsNullOrWhiteSpace(dto.receiptNo))
            {
                query = query.Where(x => x.receiptNo == dto.receiptNo || x.receiptNo.Contains(dto.receiptNo));
            }

            if (!string.IsNullOrWhiteSpace(dto.warehouseId))
            {
                query = query.Where(x => x.warehouseID == dto.warehouseId);
            }

            if (dto.Date != null)
            {
                var start = dto.Date.Value.Date.AddHours(-8);
                var end = start.AddDays(1);

                query = query.Where(x => x.addTime >= start && x.addTime < end);
            }
            await Task.CompletedTask;
            return query;
        }

        public override async Task<ResponseEntity<PagedResultDto<OtherBill>>> QueryPaging([FromBody] OtherBillPagingDto dto)
        {
            var res = await base.QueryPaging(dto);

            if (res?.Data?.Items?.Any() ?? false)
            {
                res.Data.Items = await this.otherBillService.AttachWarehouse(res.Data.Items.ToArray());
            }

            return res;
        }

        [HttpPost("add-multiple"), Obsolete]
        public async Task<ResponseEntity<OtherBill[]>> AddMultiple([FromBody] OtherBill[] data)
        {
            data.Should().NotBeNullOrEmpty();
            var no = await this.NoGeneratorService.GenerateReceiptNoAsync("QT");
            foreach (var m in data)
            {
                this.EntityHelper.InitEntity(m);
                m.receiptNo = no;
                m.isAuditing = false;
            }

            await this.Repo.InsertManyAsync(data, autoSave: true);

            return new ResponseEntity<OtherBill[]>().SetData(data);
        }

        [HttpPost("save-multiple")]
        public async Task<ResponseEntity<OtherBill[]>> SaveMultiple([FromBody] ReceiptNoItemsDto<OtherBill> data)
        {
            var res = await this.Repo.SaveReceiptItems(this.HttpContext.RequestServices, data, "QT");
            return new ResponseEntity<OtherBill[]>().SetData(res.Items);
        }

        [HttpPost("query-by-receipt-no")]
        public async Task<ResponseEntity<OtherBill[]>> QueryByReceiptNo([FromBody] ReceiptNoDto dto)
        {
            dto.Should().NotBeNull();
            dto.receiptNo.Should().NotBeNullOrEmpty();
            var query = this.SingleStoreService.ApplyToQueryable(this.Repo);
            var data = await query.Where(x => x.receiptNo == dto.receiptNo).ToArrayAsync();

            if (data.Any())
            {
                data = await this.otherBillService.AttachWarehouse(data);
                data = await this.otherBillService.AttachGoodsInfo(data);
            }

            return new ResponseEntity<OtherBill[]>().SetData(data);
        }
        [HttpPost("save-print-task")]
        public async Task<ResponseEntity<string>> SavePrintTask([FromBody] ReceiptNoDto dto)
        {
            dto.Should().NotBeNull();
            dto.receiptNo.Should().NotBeNullOrEmpty();
            var query = this.SingleStoreService.ApplyToQueryable(this.Repo);
            var data = await query.Where(x => x.receiptNo == dto.receiptNo).FirstOrDefaultAsync();
            var printTaskSaveData = new PrintTaskSaveInputDto
            {
                receiptDate = data.receiptDate,
                receiptNo = data.receiptNo,
                printTag = 0,
                printNo = "P0"
            };


            var ret = new ResponseEntity<string>();
            try
            {
                var result = await this.printTaskService.SavePrintTaskItems(printTaskSaveData);
                if (result.Item1 == 0)
                    ret.SetError("创建打印任务失败！" + result.Item2);
                ret.SetData("创建打印任务成功");
            }
            catch (Exception e)
            {
                ret.SetError("创建失败！" + e.Message);
                //logger.LogError(e.Message);
            }

            return ret;
        }

        /// <summary>
        /// 每条其他单只显示一条记录
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("query-paging-distinct")]
        public async Task<ResponseEntity<PagedResultDto<OtherBill>>> QueryPagingDistinct([FromBody] OtherBillPagingDto dto)
        {
            var query = await base.GetQueryPagingData(dto);
            var data = new PagedResultDto<OtherBill>();
            query = await this.OrderQueryPaging(query, dto);

            query = query.WhereIf(dto.Date != null, x => x.receiptDate >= dto.Date.Value);

            var list = query.ToList().GroupBy(g => new { g.receiptDate, g.receiptNo, g.warehouseID, g.inOrOut })
                .Select(x => new OtherBill
                {
                    receiptDate = x.Key.receiptDate,
                    receiptNo = x.Key.receiptNo,
                    warehouseID = x.Key.warehouseID,
                    inOrOut = x.Key.inOrOut,
                    Num = x.Sum(s => s.Num),
                    isAuditing = x.Select(a => a.isAuditing).FirstOrDefault(),
                    operateTime = x.Select(a => a.operateTime).FirstOrDefault()
                }).ToList();

            data.TotalCount = list.Count();
            //logger.LogInformation(">>>>>>>>>>>>>>>>>>TotalCount：" + data.TotalCount);
            list = list.Skip((dto.Page - 1) * dto.PageSize).Take(dto.PageSize).ToList();
            //logger.LogInformation(">>>>>>>>>>>>>>>>>>5");
            data.Items = list.ToArray();
            ResponseEntity<PagedResultDto<OtherBill>> res = new ResponseEntity<PagedResultDto<OtherBill>>().SetData(data);

            if (res.Data?.Items?.Any() ?? false)
            {
                res.Data.Items = await this.otherBillService.AttachWarehouse(res.Data.Items.ToArray());
            }

            return res;
        }
    }
}
